package org.example.utils;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;

public class JwtUtil {
    // 1. 密钥：HS256要求至少32个字符（256位），推荐用配置文件读取
    private static final String SECRET_KEY = "my-32-char-secret-key-1234567890abcdef";
    // 2. Token过期时间（如2小时）
    private static final long EXPIRATION_TIME = 2 * 60 * 60 * 1000;

    // 生成Token
    public static String generateToken(String username) {
        // 创建密钥（与解析时一致）
        SecretKey key = Keys.hmacShaKeyFor(SECRET_KEY.getBytes(StandardCharsets.UTF_8));
        
        return Jwts.builder()
                .setSubject(username) // 存储用户标识（如用户名/ID）
                .setIssuedAt(new Date()) // 签发时间
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) // 过期时间
                .signWith(key, SignatureAlgorithm.HS256) // 签名算法+密钥
                .compact();
    }

    // 解析Token，获取用户名（若签名失败/过期，会抛出异常）
    public static String getUsernameFromToken(String token) {
        SecretKey key = Keys.hmacShaKeyFor(SECRET_KEY.getBytes(StandardCharsets.UTF_8)); // 与生成时完全相同的密钥
        
        try {
            Claims claims = Jwts.parserBuilder()
                    .setSigningKey(key) // 绑定密钥，验证签名
                    .build()
                    .parseClaimsJws(token) // 解析Token（签名不匹配会抛SignatureException）
                    .getBody();
            
            return claims.getSubject(); // 返回存储的用户名
        } catch (SignatureException e) {
            throw new RuntimeException("JWT签名验证失败，Token可能被篡改或密钥错误", e);
        } catch (ExpiredJwtException e) {
            throw new RuntimeException("JWT已过期", e);
        } catch (Exception e) {
            throw new RuntimeException("JWT解析失败", e);
        }
    }

    // 测试方法
    public static void main(String[] args) {
        // 1. 生成Token
        String token = generateToken("admin");
        System.out.println("生成的Token：" + token);
        
        // 2. 解析Token
        String username = getUsernameFromToken(token);
        System.out.println("解析出的用户名：" + username); // 应输出 "admin"
    }
}